/* File:   functions.c
   Author: C Chester
   Date:   12 August 2011
   Descr:  Defines functions for the cap sensing module
*/

#include "functions.h"

long time_counter = 0;
long set_times[15];
int intializer_flag = 0;
long freqthreshold[2];
long capacitance ;


#define OFFSET 0
#define BUFFER_SIZE 15
#define CAPCONVERT1 714
#define CAPCONVERT2 12
#define USEFUL_START 5


/* Threshold finding Function*/
/*==================================================================================================================================*/
long thresh_value(long* values)
{
	long mini[2];
	mini[0] = values[USEFUL_START] ;
	
	for (long i = USEFUL_START; i< (BUFFER_SIZE); i ++)
	{
		if ((values[i]< mini[0]))
		{
			mini[0] = values[i];
		}
	}
	
	RA7 = 0; //making sure the LED hasnt been left on by calabrating
	
	return (mini[0]-OFFSET);
}
/*==================================================================================================================================*/		


/* Recalabrates Cap mat*/
/*==================================================================================================================================*/
void recalabrate(void)
{	
	intializer_flag == 0;
	time_counter = 5;
}	
/*==================================================================================================================================*/


/* Impact Detecting function*/
/*==================================================================================================================================*/
int ball_detect(long time)
{
	// Calabrates the pressure mat to find average capacitance values
	if(time_counter < BUFFER_SIZE)
	{
		RA7 = !RA7;	
		set_times[time_counter] = time;
		time_counter++;
	}
	else
	{
		if(intializer_flag == 0)
		{
			freqthreshold[0] = thresh_value(& set_times); //determines the threshold value of the mat
			capacitance = freqthreshold[0];
			capacitance = CAPCONVERT1/(capacitance - CAPCONVERT2 ); 
			intializer_flag == 1;
		}
		
		if(time < freqthreshold[0])
		{
			recalabrate();
			return 1;
		}
		
		else
		{
			return 0;
		}
	}
	
	return 0;			
}	
/*==================================================================================================================================*/	

/* Initialising Function*/
/* Uses code from PCBheaven.com*/
/*==================================================================================================================================*/
void initialise(void)
{
		TRISB = 0b00000010; 	//Sets RB1 as an input 
		TRISA = 0b00000000; 	//Sets all portA as outputs
		PORTA = 0x00;		//Clears all portA outputs
		PORTB = 0x00;		//Clears all PortB outputs
		ANSELB |= ANSB1;	//Sets RB1 as an analogue input
		
		CPSCON0 = 0b10001100;	//Enables Capacitive Sensing
		CPSCON1 = 0b00000000;	//Clears Sensing Choice
	
		
		OPTION_REG = 0b11000111;//-- Using the capacitance module with TMR0 as the reference time--//
					   
					/*
						Bit 5: TMR0 Source is internal instruction clock (Fosc/4)
						Bit 4: TRM0 Increments on low to high
						Bit 3: Prescaller assigned to TMR0 module
						Bits <2:0>: Prescaller rate is 1:256
						This gives a clock of 32M/4/64 = 125kHz
					*/
					   				
		TMR0IF = 0; 		// Clears Timer0 Interrupt Flag
		TMR0IE = 1; 		// Enables Timer0 overflow interupt
	
		T1CON = 0b11000101;  	//--Setup TMR1 module Control register--//
		
					/*	Bits <7:6>: Timer 1 source is Capacitive Sensing Oscillator
					 	Bits <5:4>: Prescaller is 1:1
						Bit 3: LP oscillatos is deactivated
						Bit 2: No synchronization
						Bit 0: Timer 1 is on
					*/
	
		T1GCON = 0b11100001;  	//--Setup Timer 1 Gate module--//
		
					/*
						Bit 7: Gate controls the counting function of TMR1 (want 1)
						Bit 6: Gate polarity is Active HIGH
						Bit 5: Gate input is through Toggle FF
						Bits <4:3>: No single pulse mode
						Bits <1:0>: Gate source is Timer0 overflow
					*/
		
		TMR1GIF = 0;		//Clear Gate interupt
		TMR1GIE = 1;		//Enable Gate interupt
		
		CPSCON1 |= 0b00001011;	// Used to set capacitive sensing pin RB1 (CPS11)
				
		ei();			//Turn on Global Interrupts
}
/*==================================================================================================================================*/	

// Resets timers after a capacitance has been measured
/*==================================================================================================================================*/
void reset_timers(void)
{
		TMR0 = 0xFF;			// Sets timer to highest position in order to reset the gate on the capcitor sensor. 
		TMR0IF = 0;			// Clears Flag
		TMR0 = 0x00;			// Resets the Timer0
		
		TMR1ON = 0;			// Stop Timer1
		TMR1L = 0x00; 			// Reset Timer1
		TMR1H = 0x00;
		TMR1 = 0x0000;
		TMR1ON = 1; 			// Restart Timer1
}
/*==================================================================================================================================*/	

